package com.zb.automation.service.impl.convertor;

import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.zb.automation.enums.ParamTypeEnum;
import com.zb.automation.model.response.JsonParamsDTO;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;

import java.math.BigDecimal;
import java.util.*;

/**
 * @Description
 * @Author ZhangBin
 * @Data 2022/7/23 14:48
 */
public class AnalysisJsonConvertor {
    private final static String NULL_REGEX = ":\\s*null";
    private final static String NULL_REPLACE_TARGET = ":\"_null_\"";
    private final static String _NULL_ = "_null_";

    public static void json2Param(List<JsonParamsDTO> list, String json) {
        json = json.replaceAll(NULL_REGEX, NULL_REPLACE_TARGET);
        JsonParamsDTO jsonParam = null;
        JSONObject jsonInfo = JSONObject.parseObject(json, JSONObject.class, Feature.OrderedField);
        Iterator iter = jsonInfo.entrySet().iterator();
        while (iter.hasNext()) {
            jsonParam = new JsonParamsDTO();
            Map.Entry entry = (Map.Entry) iter.next();
            //写成枚举
            if (entry.getValue() instanceof String) {
                if (entry.getValue() != null && entry.getValue().equals(_NULL_)) {
                    jsonParam.setParamType(ParamTypeEnum.NULL.getCode());
                    jsonParam.setParamName((entry.getKey()).toString());
                    jsonParam.setExampleValue(null);
                    list.add(jsonParam);
                    continue;
                }
                jsonParam.setParamType(ParamTypeEnum.STRING.getCode());
                jsonParam.setParamName((entry.getKey()).toString());
                jsonParam.setExampleValue((entry.getValue()).toString());
                list.add(jsonParam);
            } else if(entry.getValue() instanceof BigDecimal){
                jsonParam.setParamType(ParamTypeEnum.DOUBLE.getCode());
                jsonParam.setParamName((entry.getKey()).toString());
                jsonParam.setExampleValue((entry.getValue()).toString());
                list.add(jsonParam);
            }else if (entry.getValue() instanceof Integer) {
                jsonParam.setParamType(ParamTypeEnum.INTEGER.getCode());
                jsonParam.setParamName((entry.getKey()).toString());
                jsonParam.setExampleValue((entry.getValue()).toString());
                list.add(jsonParam);
            } else if (entry.getValue() instanceof List) {
                List<JsonParamsDTO> list1 = new ArrayList<>();
                JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(entry.getValue()));
                int keyMaxCount = 0;
                int jsonArrayIndex = -1;
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    if (jsonObject == null) {
                        continue;
                    }
                    Set<String> keySet = jsonObject.keySet();
                    if (keySet == null) {
                        continue;
                    }
                    if (keySet.size() > keyMaxCount) {
                        keyMaxCount = keySet.size();
                        jsonArrayIndex = i;
                    }
                }
                if (jsonArrayIndex != -1) {
                    json2Param(list1, JSON.toJSONString(jsonArray.getJSONObject(jsonArrayIndex)));
                }
                jsonParam.setParamType(ParamTypeEnum.ARRAY.getCode());
                jsonParam.setParamName((entry.getKey()).toString());
                jsonParam.setChildren(list1);
                list.add(jsonParam);
            } else if (entry.getValue() instanceof Object && null != entry.getValue()) {
                jsonParam.setParamType(ParamTypeEnum.OBJECT.getCode());
                jsonParam.setParamName(entry.getKey().toString());
                List<JsonParamsDTO> list3 = new ArrayList<>();
                getChild(list3, JSON.toJSONString(entry.getValue()));
                jsonParam.setChildren(list3);
                list.add(jsonParam);
            }

        }
    }

    private static void getChild(List<JsonParamsDTO> list, String json) {
        JSONObject jsonInfo = JSONObject.parseObject(json);
        JsonParamsDTO jsonParam;
        Iterator iter2 = jsonInfo.entrySet().iterator();
        while (iter2.hasNext()) {
            jsonParam = new JsonParamsDTO();
            Map.Entry entry = (Map.Entry) iter2.next();
            if (entry.getValue() instanceof String) {
                if (entry.getValue() != null && entry.getValue().equals(_NULL_)) {
                    jsonParam.setParamType(ParamTypeEnum.NULL.getCode());
                    jsonParam.setParamName((entry.getKey()).toString());
                    jsonParam.setExampleValue(null);
                    list.add(jsonParam);
                    continue;
                }
                jsonParam.setParamType(ParamTypeEnum.STRING.getCode());
                jsonParam.setParamName((entry.getKey()).toString());
                jsonParam.setExampleValue((entry.getValue()).toString());
                list.add(jsonParam);
            } else if (entry.getValue() instanceof List) {
                List<JsonParamsDTO> list1 = new ArrayList<>();
                JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(entry.getValue()));
                int keyMaxCount = 0;
                int jsonArrayIndex = -1;
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    if (jsonObject == null) {
                        continue;
                    }
                    Set<String> keySet = jsonObject.keySet();
                    if (keySet == null) {
                        continue;
                    }
                    if (keySet.size() > keyMaxCount) {
                        keyMaxCount = keySet.size();
                        jsonArrayIndex = i;
                    }

                }
                if (jsonArrayIndex != -1) {
                    getChild(list1, JSON.toJSONString(jsonArray.getJSONObject(jsonArrayIndex)));
                }
                jsonParam.setParamType(ParamTypeEnum.ARRAY.getCode());
                jsonParam.setParamName((entry.getKey()).toString());
                jsonParam.setChildren(list1);
                list.add(jsonParam);
            } else if (entry.getValue() instanceof Integer) {
                jsonParam.setParamType(ParamTypeEnum.INTEGER.getCode());
                jsonParam.setParamName((entry.getKey()).toString());
                jsonParam.setExampleValue((entry.getValue()).toString());
                list.add(jsonParam);
            } else {
                jsonParam.setParamType(ParamTypeEnum.OBJECT.getCode());
                jsonParam.setParamName((entry.getKey()).toString());
                jsonParam.setExampleValue((entry.getValue()).toString());
                list.add(jsonParam);
            }
        }
    }


    public static HorizontalCellStyleStrategy buildHorizontalCellStyleStrategy() {
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景设置为红色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short)11);
        headWriteFont.setFontName("宋体");
        headWriteFont.setBold(false);
        headWriteCellStyle.setWriteFont(headWriteFont);
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.TOP);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
        //contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 背景绿色
        //contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontName("微软雅黑");
        contentWriteFont.setFontHeightInPoints((short)11);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }
}
